-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #115 #121
base: main
Are you sure you want to change the base?
Fixes #115 #121
Conversation
@jimhester, @kevinushey Do you guys know if this change will cause problems on platforms that don't support C++17? |
Yes, it definitely will, the CXX17 macro won't be set with the current Windows toolchain for instance. |
Well actually this change doesn't actually affect Windows, since this only changes Makevars and not Makevars.win, but the underlying issue is the same, if R wasn't built with a compiler that supports C++17 then the |
Yes, I would stick with CXX11 and allow some way to opt-in to using CXX17 if supported by the active compiler. (This unfortunately does imply writing a configure script but it looks like |
Thanks, guys. There already is a configure script, so that at least reduces the amount of work needed. |
23a1645
to
1dd40c8
Compare
Finally I spent some time trying to improve the configure script. With this fix I can compile without issue in OpenBSD/adJ 6.6. In this platform, the test program that I included in configure if compiled with CXX11 gives: $ c++ -std=c++11 -c test_timespec.cpp
test_timespec.cpp:9:21: error: use of undeclared identifier 'TIME_UTC'
1 error generated. but compiled with CXX17 gives no error: $ c++ -std=c++17 -c test_timespec.cpp @wch I would appreciate if you could please check. Blessings. |
configure
Outdated
} | ||
|
||
} | ||
" | ${CXX} -x c++ -std=c++11 - -o /dev/null > /dev/null 2>&1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that there are some platforms that don't support std-=c++11
. I'm not even sure that some of the more obscure platforms (like the compiler on Solaris, which is one of the platforms used by CRAN) have the -std
option.
@vtamara I don't think the test is correct -- on the Ubuntu CI, you can see that it says that C++17 is required, but that hasn't been true in the past. It's probably because it normally would use Finding the default compiler flags used by R for C++11 can be done by calling:
However, keep in mind that not all platforms that we need to support have C++11 compilers, notably RedHat/Centos 6. |
configure
Outdated
|
||
namespace std { | ||
|
||
int main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use spaces instead of tabs.
eabcaec
to
e714e81
Compare
@wch What do you think about this one? I tested in OpenBSD/adJ 6.6 as well as Ubuntu 19.10 and looks good. Please feel free to change it to make it more portable. |
configure
Outdated
@@ -20,9 +20,50 @@ else | |||
EXTRA_PKG_LIBS=-latomic | |||
fi | |||
|
|||
CXX=$("${R_HOME}"/bin/R CMD config CXX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On some platforms, the /bin/sh
does not support $()
for running commands. You need to use backticks instead. I recently ran into this on Solaris.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I changed its use, even in the test that was already there.
configure
Outdated
CXX=$("${R_HOME}"/bin/R CMD config CXX) | ||
CXX11FLAGS=$("${R_HOME}"/bin/R CMD config CXX11FLAGS) | ||
if [ "$CXX" != "" -a "$CXX11FLAGS" != "" ]; then | ||
# Detect whether if c++11 is enough |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two spaces per level of indenting, please.
configure
Outdated
@@ -20,9 +20,50 @@ else | |||
EXTRA_PKG_LIBS=-latomic | |||
fi | |||
|
|||
CXX=$("${R_HOME}"/bin/R CMD config CXX) | |||
CXX11FLAGS=$("${R_HOME}"/bin/R CMD config CXX11FLAGS) | |||
if [ "$CXX" != "" -a "$CXX11FLAGS" != "" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment that explains the logic being used by these checks?
@vtamara I've given some feedback, but don't currently have time to test and fix on various platforms for you. I don't want to introduce breakage on platforms that are widely used, or which CRAN requires us to build on. Notable platforms include Mac, Windows, RHEL/Centos 6 (which by default does not have a compiler that supports C++11), and Solaris (which has a very outdated toolchain but which CRAN still uses for checks.) |
One more thought: it may be simpler to do something like this:
|
acc0ac8
to
e61c967
Compare
@wch I implemented the simpler method you suggested. For me it works on OpenBSD/adJ 6.6 with R 3.6.1, on Ubuntu 19.10 with R 3.6.1 and on Ubuntu 18.04 with R 3.4.4. The CI shows it works fine on macOS-latest, windows and ubuntu-16.04 with R 3.6.x, although it has problems on ubuntu-16.04 and R 3.5, 3.4, 3.3 and 3.2. On the platforms where it doesn't work it shows:
So I guess, more things should be tested before setting Any suggestion on how to test on those platform where it fails or on solaris? |
I still think the logic isn't quite right. I think it should be something like this:
A bit more detail: in the second case (where C++17 is not available), rather than simply using I believe that to check for C++17 support, you can run Just to add a bit more detail of the challenges for platform-specific stuff like this: we need to support not only the platforms that I mentioned earlier (and which we test with continuous integration) but also platforms with older versions of R, and older compilers. I noticed when I read this section of Writing R Extensions that with R 4.0, you can always assume a C++11 compiler is available; however, for older versions of R, that isn't the case. |
@wch As far as I know, in configure scripts it is not advisable to check for tools and version but if the existing tools have the features required. I think this example and the CI results show why. Since in most platforms it works with CXX_STD=CXX11, in my humble opinion it is better to change to CXX_STD=CXX17 only when test scripts for every problematic feature pass (of course identifying test script for those problematic features). |
configure
Outdated
CXX_STD=CXX11 | ||
|
||
# But if it works, use CXX17 | ||
CXX=`"${R_HOME}"/bin/R CMD config CXX` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized this should be CXX17
.
configure
Outdated
echo "Using c++17." | ||
CXX_STD=CXX17 | ||
else | ||
echo "Cannot use c++17 using default configuration for c++11" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a weird thing about R, that when one sets CXX_STD=CXX11
, it doesn't necessarily mean that it will be compiled with a C++11 compiler. It just means that if a C++11 compiler is available, it will use it. (Note that this is different from how R uses CXX14
and CXX17
.)
I understand your point of view, in trying to be conservative about the changes. If that's the idea, then this logic makes sense to me:
As I understand your code, it first looks for a C++17 compiler, and if present, it tries to compile a test program that should always pass according to the C++17 spec. The test program is therefore redundant (modulo the possibility of a non-compliant compiler, but the time stuff seems like a pretty basic part of the standard so that seems very unlikely.) But the current problem with OpenBSD is that we try to use C++11, but that standard doesn't guarantee that the time stuff is available. The test program can fail when compiling the code with a C++11 compiler (this is basically what's happening with the current release version of later), but not a C++17 compiler. However, OpenBSD does have a C++17 compiler that does make the time stuff available. A few other comments:
Just a heads up: my time is very, very limited these days, and my other responsibilities mean that I can't really spend much more time on this. |
Credit to @wch